+ Arithmetic shift operators in various programming languages and processors ! Language or processor !! Left !! Right | ||
>> | ||
<< | ||
>> | ||
Shift_Left Fortran 2008. | ||
Shift_Right_Arithmetic | ||
shl The Verilog arithmetic right shift operator only actually performs an arithmetic shift if the first operand is signed. If the first operand is unsigned, the operator actually performs a logical right shift. | ||
OpenVMS macro language | @ | |
Scheme | shr In Scheme SHIFTL can be both left and right shift, depending on the second operand, very similar to the OpenVMS macro language, although R6RS Scheme adds both SHIFTA and << variants. | |
Common Lisp | ~>> | |
<<< | ||
Haskell | >>> | |
arithmetic-shift | ||
arithmetic-shift | ||
-right | ||
-left | ||
ash, lsl |
Some authors prefer the terms sticky right-shift and zero-fill right-shift for arithmetic and logical shifts respectively. Thomas R. Cain and Alan T. Sherman. "How to break Gifford's cipher". Section 8.1: "Sticky versus Non-Sticky Bit-shifting". Cryptologia. 1997.
Arithmetic shifts can be useful as efficient ways to perform multiplication or division of signed integers by powers of two. Shifting left by n bits on a signed or unsigned binary number has the effect of multiplying it by 2 n. Shifting right by n bits on a two's complement signed binary number has the effect of dividing it by 2 n, but it always rounds down (towards negative infinity). This is different from the way rounding is usually done in signed integer division (which rounds towards 0). This discrepancy has led to bugs in a number of compilers.
For example, in the x86 instruction set, the SAR instruction (arithmetic right shift) divides a signed number by a power of two, rounding towards negative infinity. However, the IDIV instruction (signed divide) divides a signed number, rounding towards zero. So a SAR instruction cannot be substituted for an IDIV by power of two instruction nor vice versa.
An important word in the FS 1073C definition is "usually".
It is frequently stated that arithmetic right shifts are equivalent to division by a (positive, integral) power of the radix (e.g., a division by a power of 2 for binary numbers), and hence that division by a power of the radix can be optimized by implementing it as an arithmetic right shift. (A shifter is much simpler than a divider. On most processors, shift instructions will execute faster than division instructions.) Large number of 1960s and 1970s programming handbooks, manuals, and other specifications from companies and institutions such as DEC, IBM, Data General, and ANSI make such incorrect statements.
Logical right shifts are equivalent to division by a power of the radix (usually 2) only for positive or unsigned numbers. Arithmetic right shifts are equivalent to logical right shifts for positive signed numbers. Arithmetic right shifts for negative numbers in N's complement (usually two's complement) is roughly equivalent to division by a power of the radix (usually 2), where for odd numbers rounding downwards is applied (not towards 0 as usually expected).
Arithmetic right shifts for negative numbers are equivalent to division using rounding towards 0 in ones' complement representation of signed numbers as was used by some historic computers, but this is no longer in general use.
Like C, C++ had an implementation-defined right shift for signed integers until C++20. Starting in the C++20 standard, right shift of a signed integer is defined to be an arithmetic shift.
|
|